# -*- coding: utf-8 -*-
from flask import Blueprint, g
from sqlalchemy import and_, or_
from common.response import success, error
from common.error_code import ErrorCode
from dao.db import db
from dao.user_dao import User, Student, Teacher, Class
from dao.class_dao import ClassSubjectTeacher
from dao.message_dao import Message
from filter.auth import auth_required
from filter.decorators import validate_request
from model.request import MessageDetailRequest, MessageListRequest, ReplyMessageRequest, SendMessageRequest

message_bp = Blueprint('message', __name__, url_prefix='/api/message')

@message_bp.route('/send', methods=['POST'])
@auth_required
@validate_request(SendMessageRequest)
def send_message():
    """发送留言接口（基于班级和任课关系的权限校验，包含接收者角色记录）"""
    data: SendMessageRequest = g.request_data
    current_user_id = g.user_id
    
    # 获取当前用户信息
    current_user = User.query.get(current_user_id)
    if not current_user:
        return error(ErrorCode.NOT_FOUND, "当前用户不存在")
    
    current_role = current_user.role
    
    # 验证接收者ID非空
    if not data.receiver_ids:
        return error(ErrorCode.INVALID_PARAM, "接收者ID不能为空")
    
    # 验证留言内容非空
    if not data.content.strip():
        return error(ErrorCode.INVALID_PARAM, "留言内容不能为空")
    
    # 获取当前用户相关信息（用于权限校验）
    current_class_id = None
    current_student_id = None
    current_teacher_id = None
    
    if current_role == 'student':
        # 获取学生信息及所在班级
        current_student = Student.query.filter_by(user_id=current_user_id).first()
        if not current_student:
            return error(ErrorCode.NOT_FOUND, "学生信息不存在")
        current_student_id = current_student.id
        current_class_id = current_student.class_id
    else:
        # 获取教师信息
        current_teacher = Teacher.query.filter_by(user_id=current_user_id).first()
        if not current_teacher:
            return error(ErrorCode.NOT_FOUND, "教师信息不存在")
        current_teacher_id = current_teacher.id
    
    # 验证接收者有效性及班级权限，并获取接收者角色
    valid_receivers = []  # 存储元组 (receiver_id, receiver_role)
    if current_role in ['admin', 'teacher']:
        # 管理员/老师给学生发消息：接收者角色为student
        for receiver_id in data.receiver_ids:
            # 验证学生是否存在
            student = Student.query.get(receiver_id)
            if not student:
                return error(ErrorCode.NOT_FOUND, f"学生ID {receiver_id} 不存在")
            
            # 管理员可以给所有学生发消息
            if current_role == 'admin':
                valid_receivers.append((receiver_id, 'student'))
                continue
            
            # 教师只能给本班学生或自己任课班级的学生发消息
            # 1. 检查是否是学生所在班级的班主任
            class_info = Class.query.get(student.class_id)
            if class_info and class_info.head_teacher_id == current_teacher_id:
                valid_receivers.append((receiver_id, 'student'))
                continue
            
            # 2. 检查是否是学生所在班级的任课教师
            is_teacher_of_class = ClassSubjectTeacher.query.filter_by(
                class_id=student.class_id,
                teacher_id=current_teacher_id
            ).first()
            
            if is_teacher_of_class:
                valid_receivers.append((receiver_id, 'student'))
            else:
                return error(ErrorCode.FORBIDDEN, 
                            f"无权限给学生 {receiver_id} 发送消息（非本班学生或非任课教师）")
    else:  # current_role == 'student'
        # 学生给老师发消息：接收者角色为teacher
        for receiver_id in data.receiver_ids:
            # 验证教师是否存在
            teacher = Teacher.query.get(receiver_id)
            if not teacher:
                return error(ErrorCode.NOT_FOUND, f"教师ID {receiver_id} 不存在")
            
            # 验证班级信息是否存在
            class_info = Class.query.get(current_class_id)
            if not class_info:
                return error(ErrorCode.NOT_FOUND, "班级信息不存在")
            
            # 1. 检查是否是本班班主任
            if class_info.head_teacher_id == teacher.id:
                valid_receivers.append((receiver_id, 'teacher'))
                continue
            
            # 2. 检查是否是本班的任课教师
            is_teacher_of_class = ClassSubjectTeacher.query.filter_by(
                class_id=current_class_id,
                teacher_id=teacher.id
            ).first()
            
            if is_teacher_of_class:
                valid_receivers.append((receiver_id, 'teacher'))
            else:
                return error(ErrorCode.FORBIDDEN, 
                            f"无权限给教师 {receiver_id} 发送消息（非本班教师）")
    
    # 创建留言记录，包含接收者角色
    try:
        for receiver_id, receiver_role in valid_receivers:
            message = Message(
                sender_id=current_student_id if current_role == 'student' else current_teacher_id,
                sender_role=current_role,
                receiver_id=receiver_id,
                receiver_role=receiver_role,  # 记录接收者角色
                content=data.content.strip()
            )
            db.session.add(message)
        
        db.session.commit()
        return success(f"成功发送{len(valid_receivers)}条留言")
    
    except Exception as e:
        db.session.rollback()
        return error(ErrorCode.SYSTEM_ERROR, f"发送留言失败: {str(e)}")
    
@message_bp.route('/list', methods=['POST'])
@auth_required
@validate_request(MessageListRequest)
def get_message_list():
    """查询留言列表接口（修正发送者/接收者ID关联问题）"""
    data: MessageListRequest = g.request_data
    current_user_id = g.user_id
    
    # 获取当前用户信息及角色对应的ID
    current_user = User.query.get(current_user_id)
    if not current_user:
        return error(ErrorCode.NOT_FOUND, "当前用户不存在")
    
    current_role = current_user.role
    current_related_id = None  # 对应teacher.id或student.id
    
    if current_role == 'student':
        current_student = Student.query.filter_by(user_id=current_user_id).first()
        if not current_student:
            return error(ErrorCode.NOT_FOUND, "学生信息不存在")
        current_related_id = current_student.id
    else:
        current_teacher = Teacher.query.filter_by(user_id=current_user_id).first()
        if not current_teacher:
            return error(ErrorCode.NOT_FOUND, "教师信息不存在")
        current_related_id = current_teacher.id
    
    # 构建查询条件：只查询顶层留言（parent_id为NULL）
    # 且当前用户是接收者或发送者（使用角色对应的ID）
    query = Message.query.filter(
        Message.parent_id.is_(None),
        or_(
            # 当前用户是接收者
            and_(
                Message.receiver_id == current_related_id,
                Message.receiver_role == current_role
            ),
            # 当前用户是发送者
            and_(
                Message.sender_id == current_related_id,
                Message.sender_role == current_role
            )
        )
    )
    
    # 按发送者姓名筛选（部分匹配）
    if data.sender_name:
        # 根据发送者角色关联不同表查询姓名
        # 使用子查询分别处理不同角色的姓名匹配
        teacher_sender_subquery = db.session.query(Teacher.id).join(
            User, Teacher.user_id == User.id
        ).filter(User.name.like(f"%{data.sender_name}%")).subquery()
        
        student_sender_subquery = db.session.query(Student.id).join(
            User, Student.user_id == User.id
        ).filter(User.name.like(f"%{data.sender_name}%")).subquery()
        
        query = query.filter(
            or_(
                and_(
                    Message.sender_role == 'teacher',
                    Message.sender_id.in_(teacher_sender_subquery)
                ),
                and_(
                    Message.sender_role == 'student',
                    Message.sender_id.in_(student_sender_subquery)
                ),
                and_(
                    Message.sender_role == 'admin',
                    Message.sender_id == current_related_id  # 管理员只能看到自己发送的
                )
            )
        )
    
    # 按接收者姓名筛选（部分匹配）
    if data.receiver_name:
        # 根据接收者角色关联不同表查询姓名
        teacher_receiver_subquery = db.session.query(Teacher.id).join(
            User, Teacher.user_id == User.id
        ).filter(User.name.like(f"%{data.receiver_name}%")).subquery()
        
        student_receiver_subquery = db.session.query(Student.id).join(
            User, Student.user_id == User.id
        ).filter(User.name.like(f"%{data.receiver_name}%")).subquery()
        
        query = query.filter(
            or_(
                and_(
                    Message.receiver_role == 'teacher',
                    Message.receiver_id.in_(teacher_receiver_subquery)
                ),
                and_(
                    Message.receiver_role == 'student',
                    Message.receiver_id.in_(student_receiver_subquery)
                )
            )
        )
    
    # 按时间范围筛选
    if data.start_time:
        query = query.filter(Message.created_at >= data.start_time)
    if data.end_time:
        query = query.filter(Message.created_at <= data.end_time)
    
    # 只看未读留言（包括主留言未读或回复有未读）
    if data.only_unread:
        # 构建未读回复子查询
        unread_replies_subquery = db.session.query(Message.parent_id).filter(
            Message.parent_id.isnot(None),
            or_(
                # 作为接收者有未读回复
                and_(
                    Message.receiver_id == current_related_id,
                    Message.receiver_role == current_role,
                    Message.is_read == False
                ),
                # 作为发送者有未读回复（对方回复的消息）
                and_(
                    Message.sender_id == current_related_id,
                    Message.sender_role == current_role,
                    Message.is_read == False
                )
            )
        ).distinct()
        
        # 主留言未读 或者 存在未读回复
        query = query.filter(
            or_(
                # 主留言未读（区分当前用户是接收者还是发送者）
                or_(
                    and_(
                        Message.receiver_id == current_related_id,
                        Message.receiver_role == current_role,
                        Message.is_read == False
                    ),
                    and_(
                        Message.sender_id == current_related_id,
                        Message.sender_role == current_role,
                        Message.id.in_(unread_replies_subquery)
                    )
                ),
                # 存在未读回复
                Message.id.in_(unread_replies_subquery)
            )
        )
    
    # 获取满足条件的总条数
    total = query.count()
    
    # 按发送时间降序排序，添加分页
    messages = query.order_by(Message.created_at.desc()) \
                    .offset(data.offset) \
                    .limit(data.limit) \
                    .all()
    
    # 处理返回结果
    result = []
    for msg in messages:
        # 获取发送者姓名（根据角色关联不同表）
        sender_name = "未知用户"
        if msg.sender_role == 'teacher':
            teacher = Teacher.query.get(msg.sender_id)
            if teacher:
                user = User.query.get(teacher.user_id)
                sender_name = user.name if user else sender_name
        elif msg.sender_role == 'student':
            student = Student.query.get(msg.sender_id)
            if student:
                user = User.query.get(student.user_id)
                sender_name = user.name if user else sender_name
        elif msg.sender_role == 'admin':
            admin = User.query.get(msg.sender_id)
            sender_name = admin.name if admin else sender_name
        
        # 获取接收者姓名（根据角色关联不同表）
        receiver_name = "未知用户"
        if msg.receiver_role == 'teacher':
            teacher = Teacher.query.get(msg.receiver_id)
            if teacher:
                user = User.query.get(teacher.user_id)
                receiver_name = user.name if user else receiver_name
        elif msg.receiver_role == 'student':
            student = Student.query.get(msg.receiver_id)
            if student:
                user = User.query.get(student.user_id)
                receiver_name = user.name if user else receiver_name
        
        # 检查所有回复是否都已读
        all_replies_read = True
        replies = Message.query.filter(
            Message.parent_id == msg.id,
            or_(
                and_(
                    Message.receiver_id == current_related_id,
                    Message.receiver_role == current_role
                ),
                and_(
                    Message.sender_id == current_related_id,
                    Message.sender_role == current_role
                )
            )
        ).all()
        if replies:
            all_replies_read = all(reply.is_read for reply in replies)
        
        # 截取前10个字符作为内容预览
        content_preview = msg.content[:10] + ("..." if len(msg.content) > 10 else "")
        
        # 判断消息方向（自己发送的/别人发给自己的）
        message_direction = "send" if (
            msg.sender_id == current_related_id and 
            msg.sender_role == current_role
        ) else "receive"
        
        result.append({
            "id": msg.id,
            "content_preview": content_preview,
            # 发送者信息
            "sender_id": msg.sender_id,
            "sender_role": msg.sender_role,
            "sender_name": sender_name,
            # 接收者信息
            "receiver_id": msg.receiver_id,
            "receiver_role": msg.receiver_role,
            "receiver_name": receiver_name,
            # 消息方向
            "message_direction": message_direction,
            "send_time": msg.created_at.strftime("%Y-%m-%d %H:%M:%S"),
            "is_read": msg.is_read,
            "all_replies_read": all_replies_read
        })
    
    return success({
        "total": total,
        "messages": result
    })

@message_bp.route('/detail', methods=['POST'])
@auth_required
@validate_request(MessageDetailRequest)
def get_message_detail():
    """查看某条留言详情接口（包含回复列表并标记已读）"""
    data: MessageDetailRequest = g.request_data
    current_user_id = g.user_id
    
    # 获取当前用户信息及角色对应的ID
    current_user = User.query.get(current_user_id)
    if not current_user:
        return error(ErrorCode.NOT_FOUND, "当前用户不存在")
    
    current_role = current_user.role
    current_related_id = None  # 对应teacher.id或student.id
    
    if current_role == 'student':
        current_student = Student.query.filter_by(user_id=current_user_id).first()
        if not current_student:
            return error(ErrorCode.NOT_FOUND, "学生信息不存在")
        current_related_id = current_student.id
    else:
        current_teacher = Teacher.query.filter_by(user_id=current_user_id).first()
        if not current_teacher:
            return error(ErrorCode.NOT_FOUND, "教师信息不存在")
        current_related_id = current_teacher.id
    
    # 查询主留言（必须是顶层留言）
    main_message = Message.query.filter(
        Message.id == data.message_id,
        Message.parent_id.is_(None),
        or_(
            # 当前用户是主留言的接收者或发送者
            and_(
                Message.receiver_id == current_related_id,
                Message.receiver_role == current_role
            ),
            and_(
                Message.sender_id == current_related_id,
                Message.sender_role == current_role
            )
        )
    ).first()
    
    if not main_message:
        return error(ErrorCode.NOT_FOUND, "留言不存在或无查看权限")
    
    # 查询该主留言的所有回复
    replies = Message.query.filter(
        Message.parent_id == data.message_id,
        or_(
            and_(
                Message.receiver_id == current_related_id,
                Message.receiver_role == current_role
            ),
            and_(
                Message.sender_id == current_related_id,
                Message.sender_role == current_role
            )
        )
    ).order_by(Message.created_at.asc()).all()
    
    # 将当前用户作为接收者的消息标记为已读（主留言+回复）
    try:
        # 处理主留言
        if (main_message.receiver_id == current_related_id and 
            main_message.receiver_role == current_role and 
            not main_message.is_read):
            main_message.is_read = True
        
        # 处理回复
        for reply in replies:
            if (reply.receiver_id == current_related_id and 
                reply.receiver_role == current_role and 
                not reply.is_read):
                reply.is_read = True
        
        db.session.commit()
    except Exception as e:
        db.session.rollback()
        return error(ErrorCode.SYSTEM_ERROR, f"标记已读失败: {str(e)}")
    
    # 辅助函数：获取用户姓名
    def get_user_name(role, related_id):
        if role == 'student':
            student = Student.query.get(related_id)
            if student:
                user = User.query.get(student.user_id)
                return user.name if user else "未知学生"
        else:
            teacher = Teacher.query.get(related_id)
            if teacher:
                user = User.query.get(teacher.user_id)
                return user.name if user else "未知教师"
        return "未知用户"
    
    # 构建主留言信息
    main_sender_name = get_user_name(main_message.sender_role, main_message.sender_id)
    main_receiver_name = get_user_name(main_message.receiver_role, main_message.receiver_id)
    main_direction = "send" if (
        main_message.sender_id == current_related_id and 
        main_message.sender_role == current_role
    ) else "receive"
    
    # 构建回复列表
    reply_list = []
    for reply in replies:
        sender_name = get_user_name(reply.sender_role, reply.sender_id)
        receiver_name = get_user_name(reply.receiver_role, reply.receiver_id)
        direction = "send" if (
            reply.sender_id == current_related_id and 
            reply.sender_role == current_role
        ) else "receive"
        
        reply_list.append({
            "id": reply.id,
            "content": reply.content,
            "send_time": reply.created_at.strftime("%Y-%m-%d %H:%M:%S"),
            "message_direction": direction,
            "sender_name": sender_name,
            "receiver_name": receiver_name,
            "is_read": reply.is_read
        })
    
    return success({
        "main_message": {
            "id": main_message.id,
            "content": main_message.content,
            "send_time": main_message.created_at.strftime("%Y-%m-%d %H:%M:%S"),
            "message_direction": main_direction,
            "sender_name": main_sender_name,
            "receiver_name": main_receiver_name,
            "is_read": main_message.is_read
        },
        "replies": reply_list
    })

@message_bp.route('/reply', methods=['POST'])
@auth_required
@validate_request(ReplyMessageRequest)
def reply_message():
    """回复留言接口"""
    data: ReplyMessageRequest = g.request_data
    current_user_id = g.user_id
    
    # 获取当前用户信息及角色对应的ID
    current_user = User.query.get(current_user_id)
    if not current_user:
        return error(ErrorCode.NOT_FOUND, "当前用户不存在")
    
    current_role = current_user.role
    current_related_id = None  # 对应teacher.id或student.id
    
    # 获取当前用户在对应角色表中的ID
    if current_role in ['admin', 'teacher']:
        # admin和teacher都从teachers表获取ID
        current_teacher = Teacher.query.filter_by(user_id=current_user_id).first()
        if not current_teacher:
            return error(ErrorCode.NOT_FOUND, "教师信息不存在")
        current_related_id = current_teacher.id
    elif current_role == 'student':
        current_student = Student.query.filter_by(user_id=current_user_id).first()
        if not current_student:
            return error(ErrorCode.NOT_FOUND, "学生信息不存在")
        current_related_id = current_student.id
    else:
        return error(ErrorCode.FORBIDDEN, "不支持的用户角色")
    
    # 验证回复内容
    if not data.content.strip():
        return error(ErrorCode.INVALID_PARAM, "回复内容不能为空")
    
    # 查询要回复的主留言（可以是顶层留言或任何层级的回复）
    target_message = Message.query.get(data.message_id)
    if not target_message:
        return error(ErrorCode.NOT_FOUND, "目标留言不存在")
    
    # 验证当前用户是否有权回复（必须是目标留言的发送者或接收者）
    is_authorized = or_(
        and_(
            target_message.sender_id == current_related_id,
            target_message.sender_role == current_role
        ),
        and_(
            target_message.receiver_id == current_related_id,
            target_message.receiver_role == current_role
        )
    )
    
    if not db.session.query(is_authorized).scalar():
        return error(ErrorCode.FORBIDDEN, "无权限回复此留言")
    
    # 确定回复的接收者信息
    if (target_message.sender_id == current_related_id and 
        target_message.sender_role == current_role):
        # 当前用户是目标留言的发送者，回复接收者是目标留言的接收者
        receiver_id = target_message.receiver_id
        receiver_role = target_message.receiver_role
    else:
        # 当前用户是目标留言的接收者，回复接收者是目标留言的发送者
        receiver_id = target_message.sender_id
        receiver_role = target_message.sender_role
    
    # 创建回复留言记录
    try:
        reply = Message(
            sender_id=current_related_id,
            sender_role=current_role,
            receiver_id=receiver_id,
            receiver_role=receiver_role,
            parent_id=data.message_id,  # 关联到目标留言
            content=data.content.strip(),
            is_read=False  # 新回复默认为未读
        )
        db.session.add(reply)
        db.session.commit()
        
        return success({
            "reply_id": reply.id,
            "message": "回复成功"
        })
    
    except Exception as e:
        db.session.rollback()
        return error(ErrorCode.INTERNAL_ERROR, f"回复失败: {str(e)}")
